[libcxx] Fix __RAII_IncreaseAnnotator for increases >= 1 Summary: Fix suggested by @mclow.lists on D8109. Store the size of the un-poisoned vector upon construction instead of calculating it later. Reviewers: titus, mclow.lists, kcc, EricWF Reviewed By: EricWF Subscribers: mclow.lists, cfe-commits Differential Revision: http://reviews.llvm.org/D8172 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@231729 91177308-0d34-0410-b5e6-96231b3b80d8 
diff --git a/include/vector b/include/vector index 22a6343..d23164b 100644 --- a/include/vector +++ b/include/vector 
@@ -868,17 +868,17 @@  // but if an exception is thrown after that the annotation has to be undone.  struct __RAII_IncreaseAnnotator {  __RAII_IncreaseAnnotator(const vector &__v, size_type __n = 1) - : __commit(false), __v(__v), __n(__n) { + : __commit(false), __v(__v), __old_size(__v.size() + __n) {  __v.__annotate_increase(__n);  }  void __done() { __commit = true; }  ~__RAII_IncreaseAnnotator() {  if (__commit) return; - __v.__annotate_shrink(__v.size() + __n); + __v.__annotate_shrink(__old_size);  }  bool __commit; - size_type __n;  const vector &__v; + size_type __old_size;  };  #else  struct __RAII_IncreaseAnnotator { 
diff --git a/test/std/containers/sequences/vector/asan_throw.pass.cpp b/test/std/containers/sequences/vector/asan_throw.pass.cpp index a1dce4a..c100da1 100644 --- a/test/std/containers/sequences/vector/asan_throw.pass.cpp +++ b/test/std/containers/sequences/vector/asan_throw.pass.cpp 
@@ -37,6 +37,22 @@  char a;  };   +class ThrowOnCopy { +public: + ThrowOnCopy() : should_throw(false) {} + explicit ThrowOnCopy(bool should_throw) : should_throw(should_throw) {} + + ThrowOnCopy(ThrowOnCopy const & other) + : should_throw(other.should_throw) + { + if (should_throw) { + throw 0; + } + } + + bool should_throw; +}; +  void test_push_back() {  std::vector<X> v;  v.reserve(2); @@ -157,6 +173,23 @@  assert(0);  }   + +void test_insert_n2() { + std::vector<ThrowOnCopy> v(10); + v.reserve(100); + assert(v.size() == 10); + v[6].should_throw = true; + try { + v.insert(v.cbegin(), 5, ThrowOnCopy()); + assert(0); + } catch (int e) { + assert(v.size() == 11); + assert(is_contiguous_container_asan_correct(v)); + return; + } + assert(0); +} +  void test_resize() {  std::vector<X> v;  v.reserve(3); @@ -193,6 +226,7 @@  test_emplace();  test_insert_range2();  test_insert_n(); + test_insert_n2();  test_resize();  test_resize_param();  }